{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "b4b4ea39",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pds\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from matplotlib.colors import ListedColormap\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9da2e7c0",
   "metadata": {},
   "source": [
    "## 数据处理\n",
    "### 1.数据载入\n",
    "使用pandas库中的read_csv函数读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3fc91e8d",
   "metadata": {},
   "outputs": [],
   "source": [
    "wine_data = pds.read_csv('train.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1025128d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3898, 13)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wine_data.shape  # 查看数据维度"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c951cc6",
   "metadata": {},
   "source": [
    "一共3898个样本，12个特征，加一个标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "1c531679",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6    1701\n",
       "5    1283\n",
       "7     647\n",
       "4     130\n",
       "8     116\n",
       "3      18\n",
       "9       3\n",
       "Name: quality, dtype: int64"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 每一个标签下包含的样本个数\n",
    "wine_data['quality'].value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d6a4f6d",
   "metadata": {},
   "source": [
    "如题目中所说，质量在5，6，7（也就是中等）的酒数量占大多数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0e56ce00",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>fixed acidity</th>\n",
       "      <th>volatile acidity</th>\n",
       "      <th>citric acid</th>\n",
       "      <th>residual sugar</th>\n",
       "      <th>chlorides</th>\n",
       "      <th>free sulfur dioxide</th>\n",
       "      <th>total sulfur dioxide</th>\n",
       "      <th>density</th>\n",
       "      <th>pH</th>\n",
       "      <th>sulphates</th>\n",
       "      <th>alcohol</th>\n",
       "      <th>quality</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>white</td>\n",
       "      <td>6.2</td>\n",
       "      <td>0.320</td>\n",
       "      <td>0.32</td>\n",
       "      <td>2.20</td>\n",
       "      <td>0.036</td>\n",
       "      <td>15.0</td>\n",
       "      <td>70.0</td>\n",
       "      <td>0.98990</td>\n",
       "      <td>3.16</td>\n",
       "      <td>0.48</td>\n",
       "      <td>12.7</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>white</td>\n",
       "      <td>6.5</td>\n",
       "      <td>0.210</td>\n",
       "      <td>0.35</td>\n",
       "      <td>5.70</td>\n",
       "      <td>0.043</td>\n",
       "      <td>47.0</td>\n",
       "      <td>197.0</td>\n",
       "      <td>0.99392</td>\n",
       "      <td>3.24</td>\n",
       "      <td>0.50</td>\n",
       "      <td>10.1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>white</td>\n",
       "      <td>6.0</td>\n",
       "      <td>0.160</td>\n",
       "      <td>0.36</td>\n",
       "      <td>1.60</td>\n",
       "      <td>0.042</td>\n",
       "      <td>13.0</td>\n",
       "      <td>61.0</td>\n",
       "      <td>0.99143</td>\n",
       "      <td>3.22</td>\n",
       "      <td>0.54</td>\n",
       "      <td>10.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>white</td>\n",
       "      <td>6.5</td>\n",
       "      <td>0.370</td>\n",
       "      <td>0.30</td>\n",
       "      <td>2.20</td>\n",
       "      <td>0.033</td>\n",
       "      <td>39.0</td>\n",
       "      <td>107.0</td>\n",
       "      <td>0.98894</td>\n",
       "      <td>3.22</td>\n",
       "      <td>0.53</td>\n",
       "      <td>13.5</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>white</td>\n",
       "      <td>5.6</td>\n",
       "      <td>0.205</td>\n",
       "      <td>0.16</td>\n",
       "      <td>12.55</td>\n",
       "      <td>0.051</td>\n",
       "      <td>31.0</td>\n",
       "      <td>115.0</td>\n",
       "      <td>0.99564</td>\n",
       "      <td>3.40</td>\n",
       "      <td>0.38</td>\n",
       "      <td>10.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type  fixed acidity  volatile acidity  citric acid  residual sugar  \\\n",
       "0  white            6.2             0.320         0.32            2.20   \n",
       "1  white            6.5             0.210         0.35            5.70   \n",
       "2  white            6.0             0.160         0.36            1.60   \n",
       "3  white            6.5             0.370         0.30            2.20   \n",
       "4  white            5.6             0.205         0.16           12.55   \n",
       "\n",
       "   chlorides  free sulfur dioxide  total sulfur dioxide  density    pH  \\\n",
       "0      0.036                 15.0                  70.0  0.98990  3.16   \n",
       "1      0.043                 47.0                 197.0  0.99392  3.24   \n",
       "2      0.042                 13.0                  61.0  0.99143  3.22   \n",
       "3      0.033                 39.0                 107.0  0.98894  3.22   \n",
       "4      0.051                 31.0                 115.0  0.99564  3.40   \n",
       "\n",
       "   sulphates  alcohol  quality  \n",
       "0       0.48     12.7        6  \n",
       "1       0.50     10.1        6  \n",
       "2       0.54     10.8        6  \n",
       "3       0.53     13.5        7  \n",
       "4       0.38     10.8        6  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wine_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2ca4b17",
   "metadata": {},
   "source": [
    "查看葡萄酒标签，发现第一列的数据类别是非数字类型，故使用mapping方式将其转换成数字（white改成1，red改成2）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "be05a23f",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>fixed acidity</th>\n",
       "      <th>volatile acidity</th>\n",
       "      <th>citric acid</th>\n",
       "      <th>residual sugar</th>\n",
       "      <th>chlorides</th>\n",
       "      <th>free sulfur dioxide</th>\n",
       "      <th>total sulfur dioxide</th>\n",
       "      <th>density</th>\n",
       "      <th>pH</th>\n",
       "      <th>sulphates</th>\n",
       "      <th>alcohol</th>\n",
       "      <th>quality</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>6.2</td>\n",
       "      <td>0.320</td>\n",
       "      <td>0.32</td>\n",
       "      <td>2.20</td>\n",
       "      <td>0.036</td>\n",
       "      <td>15.0</td>\n",
       "      <td>70.0</td>\n",
       "      <td>0.98990</td>\n",
       "      <td>3.16</td>\n",
       "      <td>0.48</td>\n",
       "      <td>12.7</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>6.5</td>\n",
       "      <td>0.210</td>\n",
       "      <td>0.35</td>\n",
       "      <td>5.70</td>\n",
       "      <td>0.043</td>\n",
       "      <td>47.0</td>\n",
       "      <td>197.0</td>\n",
       "      <td>0.99392</td>\n",
       "      <td>3.24</td>\n",
       "      <td>0.50</td>\n",
       "      <td>10.1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.0</td>\n",
       "      <td>6.0</td>\n",
       "      <td>0.160</td>\n",
       "      <td>0.36</td>\n",
       "      <td>1.60</td>\n",
       "      <td>0.042</td>\n",
       "      <td>13.0</td>\n",
       "      <td>61.0</td>\n",
       "      <td>0.99143</td>\n",
       "      <td>3.22</td>\n",
       "      <td>0.54</td>\n",
       "      <td>10.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>6.5</td>\n",
       "      <td>0.370</td>\n",
       "      <td>0.30</td>\n",
       "      <td>2.20</td>\n",
       "      <td>0.033</td>\n",
       "      <td>39.0</td>\n",
       "      <td>107.0</td>\n",
       "      <td>0.98894</td>\n",
       "      <td>3.22</td>\n",
       "      <td>0.53</td>\n",
       "      <td>13.5</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.0</td>\n",
       "      <td>5.6</td>\n",
       "      <td>0.205</td>\n",
       "      <td>0.16</td>\n",
       "      <td>12.55</td>\n",
       "      <td>0.051</td>\n",
       "      <td>31.0</td>\n",
       "      <td>115.0</td>\n",
       "      <td>0.99564</td>\n",
       "      <td>3.40</td>\n",
       "      <td>0.38</td>\n",
       "      <td>10.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   type  fixed acidity  volatile acidity  citric acid  residual sugar  \\\n",
       "0   0.0            6.2             0.320         0.32            2.20   \n",
       "1   0.0            6.5             0.210         0.35            5.70   \n",
       "2   0.0            6.0             0.160         0.36            1.60   \n",
       "3   0.0            6.5             0.370         0.30            2.20   \n",
       "4   0.0            5.6             0.205         0.16           12.55   \n",
       "\n",
       "   chlorides  free sulfur dioxide  total sulfur dioxide  density    pH  \\\n",
       "0      0.036                 15.0                  70.0  0.98990  3.16   \n",
       "1      0.043                 47.0                 197.0  0.99392  3.24   \n",
       "2      0.042                 13.0                  61.0  0.99143  3.22   \n",
       "3      0.033                 39.0                 107.0  0.98894  3.22   \n",
       "4      0.051                 31.0                 115.0  0.99564  3.40   \n",
       "\n",
       "   sulphates  alcohol  quality  \n",
       "0       0.48     12.7        6  \n",
       "1       0.50     10.1        6  \n",
       "2       0.54     10.8        6  \n",
       "3       0.53     13.5        7  \n",
       "4       0.38     10.8        6  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "size_mapping = {'white':0.0, 'red':1.0}\n",
    "wine_data['type'] = wine_data['type'].map(size_mapping)\n",
    "\n",
    "# 查看一下修改后的标签\n",
    "wine_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02681650",
   "metadata": {},
   "source": [
    "### 2.空缺值处理\n",
    "查看是否有空缺值及其数量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e54ebf9b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "type                    0\n",
       "fixed acidity           6\n",
       "volatile acidity        4\n",
       "citric acid             2\n",
       "residual sugar          1\n",
       "chlorides               2\n",
       "free sulfur dioxide     0\n",
       "total sulfur dioxide    0\n",
       "density                 0\n",
       "pH                      6\n",
       "sulphates               2\n",
       "alcohol                 0\n",
       "quality                 0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wine_data.isnull().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5fcf1ce",
   "metadata": {},
   "source": [
    "数量不是很多，直接删除含有空缺值那一行样本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ea75081f",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# 异常数据处理\n",
    "wine_data = wine_data.replace('?', np.nan)\n",
    "# 只要有一个以上的空值，删除该行\n",
    "df = wine_data.dropna(how=\"any\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9dc94a5",
   "metadata": {},
   "source": [
    "删除了6+4+2+1+6+2=21个样本数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b1fe547d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "type                    0\n",
       "fixed acidity           0\n",
       "volatile acidity        0\n",
       "citric acid             0\n",
       "residual sugar          0\n",
       "chlorides               0\n",
       "free sulfur dioxide     0\n",
       "total sulfur dioxide    0\n",
       "density                 0\n",
       "pH                      0\n",
       "sulphates               0\n",
       "alcohol                 0\n",
       "quality                 0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "133da92a",
   "metadata": {},
   "source": [
    "### 2.数据集划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "7721f50d",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = df.iloc[:,:-1].values\n",
    "y= df['quality'].values"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3cd92c5",
   "metadata": {},
   "source": [
    "## 标准化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "431b5d46",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实例化\n",
    "sc = StandardScaler()\n",
    "\n",
    "# 对数据集进行标准化（在训练集中直接进行均值和方差的计算，直接在测试集中使用）\n",
    "x_std = sc.fit_transform(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "791e8d10",
   "metadata": {},
   "source": [
    "## 利用逻辑回归预测标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a7875b45",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实例化\n",
    "lr = LogisticRegression(max_iter=10000)\n",
    "# 模型训练\n",
    "lr = lr.fit(x_std, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a7c0071a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr train score:0.544\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\python\\anaconda\\source\\lib\\site-packages\\sklearn\\model_selection\\_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.5366238776188893\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "print('lr train score:{:.3f}'.format(lr.score(x_std,y))) \n",
    "score = cross_val_score(lr,x_std,y,cv=5,scoring='accuracy')\n",
    "print(np.mean(score))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb4690cf",
   "metadata": {},
   "source": [
    "预测准确率只有百分之52.5%，效果很不理想.\n",
    "交叉验证准确率也只有52%左右。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a29c5895",
   "metadata": {},
   "source": [
    "## 尝试使用随机森林的方法进行标签预测\n",
    "随机森林就是通过集成学习的思想将多棵树集成的一种算法，它的基本单元是决策树，而它的本质属于机器学习的一大分支——集成学习（Ensemble Learning）方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "b6e5dfdc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.6423418689723978\n"
     ]
    }
   ],
   "source": [
    "from sklearn import ensemble\n",
    "#设置随机深林分类模型\n",
    "rf = ensemble.RandomForestClassifier(215) #设置100个决策树\n",
    "from sklearn.model_selection import cross_val_score\n",
    "# 交叉验证\n",
    "rf.fit(x_std, y)\n",
    "score = cross_val_score(rf,x_std,y,cv=5,scoring='accuracy')\n",
    "print(np.mean(score))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9b04876",
   "metadata": {},
   "source": [
    "准确率达到了64.2%"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a313b8d8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'n_estimators': 215}\n"
     ]
    }
   ],
   "source": [
    "# 使用RandomForestClassifier构建一个分类器，n_estimators是使用最大投票数或均值建立子树的数量\n",
    "# 选取的参数\n",
    "param_rfc = {\n",
    "            \"n_estimators\": [180,195,200,205,210,215,220]\n",
    "            }\n",
    "# GridSearchCV暴力搜索\n",
    "grid_rfc = GridSearchCV(rf, param_rfc, iid = False, cv = 5)\n",
    "grid_rfc.fit(x_std, y)\n",
    "best_param_rfc = grid_rfc.best_params_\n",
    "# best_param_rfc是已取得最佳结果的参数的组合\n",
    "print(best_param_rfc)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0a0fece",
   "metadata": {},
   "source": [
    "使用暴力搜索的方法确定决策树的最佳设置个数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0dbaabb3",
   "metadata": {},
   "source": [
    "## 用训练好的模型进行标签预测\n",
    "对test.csv中的样本进行标签预测，将生成结果放入submission.csv中用于提交"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "5f74e7cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_data = pds.read_csv('test.csv')\n",
    "\n",
    "# 文本标签转数字标签\n",
    "size_mapping = {'white':0.0, 'red':1.0}\n",
    "test_data['type'] = test_data['type'].map(size_mapping)\n",
    "\n",
    "# 异常数据处理\n",
    "test_data = test_data.replace('?', np.nan)\n",
    "# 由于需要提交，对空缺值选择使用填充的方式处理\n",
    "df = test_data.fillna(method=\"ffill\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "c24ca36b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2599, 12)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 取数据进行标准化\n",
    "T = wine_test.iloc[:,0:12].values\n",
    "T_std = sc.transform(T)\n",
    "T.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "30704167",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "quality\n",
       "6          1379\n",
       "5           862\n",
       "7           328\n",
       "8            18\n",
       "4            12\n",
       "dtype: int64"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T_pred = rf.predict(T_std) #返回 X 的预测值 y\n",
    "a = pds.DataFrame()\n",
    "a['quality'] = list(T_pred)\n",
    "a.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "1fd9d3eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "a.to_csv('submission.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d311e4dc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
